package com.gitee.morilys.jsmile.gen.gentable;

import com.gitee.morilys.jsmile.gen.db.DBUtils;
import com.gitee.morilys.jsmile.gen.db.StrUtil;
import com.google.common.collect.Lists;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.List;

public class GenTables {

	private String[] removedTableNamePrefixes = null;
	private String[] tableNames = null;
	private Connection conn = null;
	private String basePackname = null;
	private String baseVoPackname = null;
	private String baseToPackname = null;
	private String baseDaoPackname = null;
	private String baseRepoPackname;
	private String baseSearchRepoPackname;
	private String baseServicePackname = null;
	private String mybatisPath = null;

	public GenTables() {
		this.conn = DBUtils.getConnection();
		this.basePackname = DBUtils.basePackname;
		this.baseVoPackname = DBUtils.baseVoPackname;
		this.baseToPackname = DBUtils.baseToPackname;
		this.baseDaoPackname = DBUtils.baseDaoPackname;
		this.baseServicePackname = DBUtils.baseServicePackname;
		this.baseRepoPackname = DBUtils.baseRepoPackname;
		this.baseSearchRepoPackname = DBUtils.baseSearchRepoPackname;
		this.tableNames = DBUtils.tableNames;
		this.removedTableNamePrefixes = DBUtils.removedTableNamePrefixes;
		this.mybatisPath = DBUtils.mybatisPath;
	}

	public static GenTables me() {
		return new GenTables();
	}

	/**
	 * 自动生成代码，返回Table实体
	 */
	public List<Table> getTables() {
		List<Table> tables = Lists.newArrayList();
		try {
			DatabaseMetaData dbmd = conn.getMetaData();
			if (tableNames != null && tableNames.length > 0) {
				for (int i = 0; i < tableNames.length; i++) {
					String primarykey = null;
					Table table = new Table();
					table.setTableName(tableNames[i].trim());
					table.setEntityPackageName(basePackname);
					table.setEntityVoPackageName(baseVoPackname);
					table.setEntityToPackageName(baseToPackname);
					table.setDaoPackageName(baseDaoPackname);
					table.setServicePackageName(baseServicePackname);
					table.setBaseRepoPackname(baseRepoPackname);
					table.setBaseSearchRepoPackname(baseSearchRepoPackname);
					table.setMybatisPath(mybatisPath);
					table.setClassName(getRealTableName(tableNames[i]));
					List<Column> columnsList = Lists.newArrayList();
					ResultSet rs = dbmd.getColumns(null, null, tableNames[i], "%");
					ResultSet primaryKeys = dbmd.getPrimaryKeys(conn.getCatalog(), null, tableNames[i]);
					while (primaryKeys.next()) {
						primarykey = primaryKeys.getString("COLUMN_NAME");
					}
					table.setPrimarykey(primarykey);
					while (rs.next()) {
						String columnName = rs.getString("COLUMN_NAME");
						Column column = new Column();
						column.setColumnName(columnName);
						column.setColumnDesc(rs.getString("REMARKS"));
						column.setColumnType(sqlType2JavaType(rs.getString("COLUMN_NAME"), rs.getString("TYPE_NAME")));
						if (null!=primarykey&&primarykey.equals(column.getColumnName())) {
							column.setIsPrimaryKey("true");
						}
						columnsList.add(column);
					}
					table.setColumns(columnsList);
					tables.add(table);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtils.close(conn);
		}
		return tables;
	}



	/**
	 * 获取实体名称
	 */
	public String getRealTableName(String tablename) {
		String str = tablename;
		if (removedTableNamePrefixes != null && removedTableNamePrefixes.length > 0) {
			for (String s : removedTableNamePrefixes) {
				if(tablename.contains(s)) {
					str = str.substring(s.length(), str.length());
					break;
				}
			}
		}
		str = StrUtil.underlineToCamelhump(str.trim());
		str = StrUtil.firstCharToUpperCase(str.trim());
		return str;
	}

	/**
	 * 功能：获得列的数据类型
	 * 
	 * @param sqlType
	 * @return
	 */
	private String sqlType2JavaType(String columnName, String sqlType) {
		if (sqlType.equalsIgnoreCase("bit")) {
			return "Boolean";
		} else if (sqlType.equalsIgnoreCase("tinyint")||sqlType.equalsIgnoreCase("TINYINT UNSIGNED")) {
			return "Integer";
		} else if (sqlType.equalsIgnoreCase("smallint")) {
			return "Integer";
		} else if (sqlType.equalsIgnoreCase("int")||sqlType.equalsIgnoreCase("INT UNSIGNED")) {
			return "Integer";
		} else if (sqlType.equalsIgnoreCase("bigint")||sqlType.equalsIgnoreCase("BIGINT UNSIGNED")) {
			return "Long";
		} else if (sqlType.equalsIgnoreCase("float")) {
			return "Float";
		}else if (sqlType.equalsIgnoreCase("double")) {
			return "java.math.BigDecimal";
		} else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric") || sqlType.equalsIgnoreCase("real")
				|| sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")) {
			return "java.math.BigDecimal";
		} else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("nvarchar")
				|| sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("text")) {
			return "String";
		} else if (sqlType.equalsIgnoreCase("datetime") || sqlType.equalsIgnoreCase("timestamp")) {
			return "java.util.Date";
		} else if (sqlType.equalsIgnoreCase("image")) {
			return "java.sql.Blod";
		} else if (sqlType.equalsIgnoreCase("boolean")) {
			return "Boolean";
		}

		return "String";
	}

	public void setTableNames(String... tableNames) {
		this.tableNames = tableNames;
	}

	public void setRemovedTableNamePrefixes(String... removedTableNamePrefixes) {
		this.removedTableNamePrefixes = removedTableNamePrefixes;
	}

	public String getBasePackname() {
		return basePackname;
	}

	public void setBasePackname(String baseVoPackname) {
		if (baseVoPackname == null) {
			throw new RuntimeException("实体类包名不能为空!");
		}
		this.baseVoPackname = baseVoPackname;
	}
	public void setVoBasePackname(String basePackname) {
		if (basePackname == null) {
			throw new RuntimeException("Vo类包名不能为空!");
		}
		this.basePackname = basePackname;
	}
	public void setToBasePackname(String baseToPackname) {
		if (baseToPackname == null) {
			throw new RuntimeException("To包名不能为空!");
		}
		this.baseToPackname = baseToPackname;
	}

	public void setMybatisPath(String mybatisPath) {
		if (mybatisPath == null) {
			throw new RuntimeException("mybatis路径不能为空!");
		}
		this.mybatisPath = mybatisPath;
	}

	public String[] getRemovedTableNamePrefixes() {
		return removedTableNamePrefixes;
	}

	public String[] getTableNames() {
		return tableNames;
	}

	public Connection getConn() {
		return conn;
	}

	public String getBaseVoPackname() {
		return baseVoPackname;
	}

	public String getBaseToPackname() {
		return baseToPackname;
	}

	public String getMybatisPath() {
		return mybatisPath;
	}
}
